package com.ln.jvm;

/**
 * <pre>
 *  逃脱回收实验
 *  SAVE_HOOK 对象的 finalize()方法确实被 GC 收集器触发过，并且在被收集前成功逃脱了。
 *  另外一个值得注意的地方就是，代码中有两段完全 一 样的代码片段，执行结果却是一次逃脱成功， 一次失败>
 *  这是因为任何一个对象的 finalize()方 法都只会被系统自动调用一次，如果对象面临下一次回收，它的 finalize()方法不会被再次执行，
 *  因此第 2 段代码的自救行动失败了。
 * </pre>
 *
 * @Author zhangj
 * @Date 2022/7/1 17:27
 */
public class FinalizeExcapeGC {

    public static FinalizeExcapeGC SAVE_HOOK = null;


    @Override
    @SuppressWarnings("deprecation")
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("GC已经执行了");
        FinalizeExcapeGC.SAVE_HOOK = this;
    }

    public static void main(String[] args) throws InterruptedException {
        SAVE_HOOK = new FinalizeExcapeGC();
        SAVE_HOOK = null;
        System.gc();
        // 由于 Finalizer 优先级很低，暂停0.5秒等待
        Thread.sleep(500);
        if(SAVE_HOOK != null) {
            System.out.println("我还活着...");
        } else {
            System.out.println("我挂了...");
        }

        // 再来一遍
        SAVE_HOOK = null;
        System.gc();
        // 由于 Finalizer 优先级很低，暂停0.5秒等待
        Thread.sleep(500);
        if(SAVE_HOOK != null) {
            System.out.println("我还活着...");
        } else {
            System.out.println("我挂了...");
        }
    }
}
